//
// File: spdiags.cpp
//
// MATLAB Coder version            : 5.4
// C/C++ source code generated on  : 27-Mar-2025 11:51:36
//

// Include Files
#include "spdiags.h"
#include "anonymous_function.h"
#include "detrendIBI_priors_internal_types.h"
#include "introsort.h"
#include "rt_nonfinite.h"
#include "sparse.h"
#include "coder_array.h"
#include <cmath>

// Function Definitions
//
// Arguments    : const ::coder::array<double, 2U> &arg1
//                double arg3
//                double arg4
//                sparse *res1
// Return Type  : void
//
namespace coder {
void spdiags(const ::coder::array<double, 2U> &arg1, double arg3, double arg4,
             sparse *res1)
{
  anonymous_function b_this;
  array<double, 2U> idx;
  array<double, 1U> aDat;
  array<double, 1U> i;
  array<int, 2U> r;
  array<int, 1U> aCols;
  array<int, 1U> sortedIndices;
  array<int, 1U> t;
  double len_data[4];
  double minAdjustedDim_data[3];
  double d;
  int mGEn;
  int nm1d2;
  int ns;
  int trueCount;
  signed char d_data[3];
  trueCount = 0;
  if ((-arg3 + 1.0 <= 0.0) && (arg4 - 1.0 >= 0.0)) {
    trueCount = 1;
  }
  if ((-arg3 + 1.0 <= 1.0) && (arg4 - 1.0 >= 1.0)) {
    trueCount++;
  }
  if ((-arg3 + 1.0 <= 2.0) && (arg4 - 1.0 >= 2.0)) {
    trueCount++;
  }
  ns = 0;
  if ((-arg3 + 1.0 <= 0.0) && (arg4 - 1.0 >= 0.0)) {
    d_data[0] = 0;
    ns = 1;
  }
  if ((-arg3 + 1.0 <= 1.0) && (arg4 - 1.0 >= 1.0)) {
    d_data[ns] = 1;
    ns++;
  }
  if ((-arg3 + 1.0 <= 2.0) && (arg4 - 1.0 >= 2.0)) {
    d_data[ns] = 2;
  }
  mGEn = (arg3 >= arg4);
  len_data[0] = 0.0;
  for (ns = 0; ns < trueCount; ns++) {
    d = std::fmin(arg3, arg4 - static_cast<double>(d_data[ns]));
    minAdjustedDim_data[ns] = d;
    len_data[ns + 1] = ((len_data[ns] + d) - 1.0) + 1.0;
  }
  nm1d2 = static_cast<int>(len_data[trueCount]);
  b_this.workspace.a.set_size(nm1d2);
  for (int k{0}; k < nm1d2; k++) {
    b_this.workspace.a[k] = 0;
  }
  aCols.set_size(nm1d2);
  for (int k{0}; k < nm1d2; k++) {
    aCols[k] = 0;
  }
  aDat.set_size(nm1d2);
  for (int k{0}; k < nm1d2; k++) {
    aDat[k] = 0.0;
  }
  for (int b_k{0}; b_k < trueCount; b_k++) {
    boolean_T guard1{false};
    d = minAdjustedDim_data[b_k];
    if (std::isnan(d)) {
      idx.set_size(1, 1);
      idx[0] = rtNaN;
    } else if (d < 1.0) {
      idx.set_size(1, 0);
    } else if (std::isinf(d) && (d == 1.0)) {
      idx.set_size(1, 1);
      idx[0] = rtNaN;
    } else {
      nm1d2 = static_cast<int>(d - 1.0);
      idx.set_size(1, static_cast<int>(d - 1.0) + 1);
      for (int k{0}; k <= nm1d2; k++) {
        idx[k] = static_cast<double>(k) + 1.0;
      }
    }
    i.set_size(idx.size(1));
    nm1d2 = idx.size(1);
    for (int k{0}; k < nm1d2; k++) {
      i[k] = idx[k];
    }
    d = len_data[b_k];
    guard1 = false;
    if (std::isnan(d + 1.0)) {
      guard1 = true;
    } else {
      double d1;
      d1 = len_data[b_k + 1];
      if (std::isnan(d1)) {
        guard1 = true;
      } else if (d1 < d + 1.0) {
        idx.set_size(1, 0);
      } else if ((std::isinf(d + 1.0) || std::isinf(d1)) && (d + 1.0 == d1)) {
        idx.set_size(1, 1);
        idx[0] = rtNaN;
      } else if (std::floor(d + 1.0) == d + 1.0) {
        nm1d2 = static_cast<int>(d1 - (d + 1.0));
        idx.set_size(1, nm1d2 + 1);
        for (int k{0}; k <= nm1d2; k++) {
          idx[k] = (len_data[b_k] + 1.0) + static_cast<double>(k);
        }
      } else {
        double apnd;
        double cdiff;
        double ndbl;
        ndbl = std::floor((d1 - (d + 1.0)) + 0.5);
        apnd = (d + 1.0) + ndbl;
        cdiff = apnd - d1;
        if (std::abs(cdiff) < 4.4408920985006262E-16 *
                                  std::fmax(std::abs(d + 1.0), std::abs(d1))) {
          ndbl++;
          apnd = d1;
        } else if (cdiff > 0.0) {
          apnd = (d + 1.0) + (ndbl - 1.0);
        } else {
          ndbl++;
        }
        if (ndbl >= 0.0) {
          ns = static_cast<int>(ndbl);
        } else {
          ns = 0;
        }
        idx.set_size(1, ns);
        if (ns > 0) {
          idx[0] = d + 1.0;
          if (ns > 1) {
            idx[ns - 1] = apnd;
            nm1d2 = (ns - 1) / 2;
            for (int k{0}; k <= nm1d2 - 2; k++) {
              idx[k + 1] =
                  (len_data[b_k] + 1.0) + (static_cast<double>(k) + 1.0);
              idx[(ns - k) - 2] = apnd - (static_cast<double>(k) + 1.0);
            }
            if (nm1d2 << 1 == ns - 1) {
              idx[nm1d2] = ((len_data[b_k] + 1.0) + apnd) / 2.0;
            } else {
              idx[nm1d2] = (len_data[b_k] + 1.0) + static_cast<double>(nm1d2);
              idx[nm1d2 + 1] = apnd - static_cast<double>(nm1d2);
            }
          }
        }
      }
    }
    if (guard1) {
      idx.set_size(1, 1);
      idx[0] = rtNaN;
    }
    r.set_size(1, idx.size(1));
    nm1d2 = idx.size(1);
    for (int k{0}; k < nm1d2; k++) {
      r[k] = static_cast<int>(idx[k]);
    }
    nm1d2 = r.size(1);
    for (int k{0}; k < nm1d2; k++) {
      b_this.workspace.a[r[k] - 1] = static_cast<int>(i[k]);
    }
    nm1d2 = r.size(1);
    for (int k{0}; k < nm1d2; k++) {
      aCols[r[k] - 1] =
          static_cast<int>(i[k] + static_cast<double>(d_data[b_k]));
    }
    ns = mGEn * d_data[b_k];
    nm1d2 = r.size(1);
    for (int k{0}; k < nm1d2; k++) {
      aDat[r[k] - 1] = arg1[(static_cast<int>(i[k] + static_cast<double>(ns)) +
                             arg1.size(0) * b_k) -
                            1];
    }
  }
  mGEn = aCols.size(0);
  ns = b_this.workspace.a.size(0);
  b_this.workspace.b.set_size(b_this.workspace.a.size(0));
  for (int b_k{0}; b_k < ns; b_k++) {
    b_this.workspace.b[b_k] = b_this.workspace.a[b_k];
  }
  ns = aCols.size(0);
  b_this.workspace.a.set_size(aCols.size(0));
  for (int b_k{0}; b_k < ns; b_k++) {
    b_this.workspace.a[b_k] = aCols[b_k];
  }
  sortedIndices.set_size(aCols.size(0));
  for (int b_k{0}; b_k < mGEn; b_k++) {
    sortedIndices[b_k] = b_k + 1;
  }
  internal::introsort(sortedIndices, b_this.workspace.a.size(0), &b_this);
  ns = b_this.workspace.a.size(0);
  t.set_size(b_this.workspace.a.size(0));
  nm1d2 = b_this.workspace.a.size(0);
  for (int k{0}; k < nm1d2; k++) {
    t[k] = b_this.workspace.a[k];
  }
  for (int b_k{0}; b_k < ns; b_k++) {
    b_this.workspace.a[b_k] = t[sortedIndices[b_k] - 1];
  }
  ns = b_this.workspace.b.size(0);
  t.set_size(b_this.workspace.b.size(0));
  nm1d2 = b_this.workspace.b.size(0);
  for (int k{0}; k < nm1d2; k++) {
    t[k] = b_this.workspace.b[k];
  }
  for (int b_k{0}; b_k < ns; b_k++) {
    b_this.workspace.b[b_k] = t[sortedIndices[b_k] - 1];
  }
  res1->m = static_cast<int>(arg3);
  nm1d2 = static_cast<int>(arg4);
  res1->n = static_cast<int>(arg4);
  ns = aCols.size(0);
  if (ns < 1) {
    ns = 1;
  }
  res1->d.set_size(ns);
  res1->maxnz = ns;
  res1->colidx.set_size(static_cast<int>(arg4) + 1);
  res1->colidx[0] = 1;
  res1->rowidx.set_size(ns);
  for (int k{0}; k < ns; k++) {
    res1->d[k] = 0.0;
    res1->rowidx[k] = 0;
  }
  ns = 0;
  for (int k{0}; k < nm1d2; k++) {
    while ((ns + 1 <= mGEn) && (b_this.workspace.a[ns] == k + 1)) {
      res1->rowidx[ns] = b_this.workspace.b[ns];
      ns++;
    }
    res1->colidx[k + 1] = ns + 1;
  }
  for (int b_k{0}; b_k < mGEn; b_k++) {
    res1->d[b_k] = aDat[sortedIndices[b_k] - 1];
  }
  res1->fillIn();
}

} // namespace coder

//
// File trailer for spdiags.cpp
//
// [EOF]
//
